﻿using System;

namespace Kobets.Automation.Chimera.Common
{
    /// <summary>
    /// Provides a generic wrapper that instantiates object in a separate AppDomain
    /// Used mainly for badly written or unmanaged objects that cannot dispose of themselves properly
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public sealed class DisposableWrapper<T> : IDisposable where T : MarshalByRefObject
    {
        private AppDomain _domain;
        private readonly T _value;

        public DisposableWrapper()
        {
            _domain = AppDomain.CreateDomain("DisposableWrapper:" + Guid.NewGuid(), null, AppDomain.CurrentDomain.SetupInformation);
            var type = typeof(T);
            _value = (T)_domain.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName);
        }

        public T Value
        {
            get
            {
                return _value;
            }
        }

        public void Dispose()
        {
            if (_domain == null) return;
            AppDomain.Unload(_domain);
            _domain = null;
        }
    }
}
